package cn.getech.data.development.utils.oozie;

import cn.getech.data.development.constant.JobType;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.List;
import java.util.Objects;

public class WorkflowXmlUtils {

    /***
     * 初始化workflow
     * @param name 名字
     * @param flageLay  是否是工作流依赖  0:工作流  1：工作流依赖
     * @return xml对象
     */
    public static Document initXml(String name,Integer flageLay){
        Document doc = DocumentHelper.createDocument();
        doc.setXMLEncoding("UTF-8");
        //创建根元素
        Element root = doc.addElement("workflow:workflow-app")
                .addAttribute("xmlns:workflow","uri:oozie:workflow:1.0").addAttribute("xmlns:shell","uri:oozie:shell-action:1.0").addAttribute("name",name)
                .addNamespace("workflow","uri:oozie:workflow:1.0")
                .addNamespace("shell","uri:oozie:shell-action:1.0");
        //添加默认开始节点
        root.addElement("workflow:start").addAttribute("to","Start_0");
        //添加默认的kill节点
        root.addElement("workflow:kill").addAttribute("name","kill")
                .addElement("workflow:message").setText("Action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]");
        //添加默认的结束节点
        root.addElement("workflow:end").addAttribute("name","end");

        //追加结束节点
        addAction(doc, JobType.ObjOf(5).getEnName() + "_0","end","kill",null,null,flageLay);

        return doc;
    }

    /***
     * 添加action
     * @param document          文档对象
     * @param execPath         文件路径
     * @param okToName         成功执行
     * @param errorToName      失败执行
     * @param retryMax         重试次数
     * @param retryInterval    重试间隔时间 单位：分钟
     * @param flageLay    是否是工作流依赖  0:工作流  1：工作流依赖
     */
    public static void addAction(Document document,String execPath,String okToName,String errorToName,String retryMax,String retryInterval,Integer flageLay){
        //获取根元素
        Element rootElement = document.getRootElement();
        Element actionElement = rootElement.addElement("workflow:action").addAttribute("name", execPath);
        if(StringUtils.isNotEmpty(retryMax)){
            actionElement.addAttribute("retry-max",retryMax);
        }
        if(StringUtils.isNotEmpty(retryInterval)){
            actionElement.addAttribute("retry-interval",retryInterval);
        }
        Element shellElement = actionElement.addElement("shell:shell");
        shellElement.addElement("shell:resource-manager").setText("${resourceManager}");
        shellElement.addElement("shell:name-node").setText("${nameNode}");
        Element proElement = shellElement.addElement("shell:configuration").addElement("shell:property");
        proElement.addElement("shell:name").setText("mapred.job.queue.name");
        proElement.addElement("shell:value").setText("${queueName}");

        shellElement.addElement("shell:exec").setText("${EXEC"+execPath+"}");
        //用于传递参数
        if(Objects.equals(1,flageLay)){
            shellElement.addElement("shell:argument").setText("${wf:actionData('Start_0').depOOzieId}");
        }
        shellElement.addElement("shell:file").setText("${nameNode}/${rootDir}/${EXEC"+execPath+"}#${EXEC"+execPath+"}");
        shellElement.addElement("shell:capture-output");

        actionElement.addElement("workflow:ok").addAttribute("to",okToName);
        actionElement.addElement("workflow:error").addAttribute("to",errorToName);

    }

    /***
     * 添加到条件的switch
     * @param document      文档对象
     * @param decisionName  switch名字
     * @param fromName      来源action的名字
     * @param objs          带条件的对象集合
     */
    public static void addCondition(Document document, String decisionName, String fromName, List<JSONObject> objs){
        //获取根元素
        Element rootElement = document.getRootElement();
        Element swithElement = rootElement.addElement("workflow:decision").addAttribute("name", decisionName)
                .addElement("workflow:switch");
        if(CollectionUtil.isNotEmpty(objs)){
            for (JSONObject obj : objs) {
                String workFlowNodeName = obj.getString("workFlowNodeName");
                String toName = obj.getString("toName");
                if(workFlowNodeName.contains("def_")){
                    swithElement.addElement("workflow:default").addAttribute("to",toName);
                }else{
                    String routeCondit = obj.getString("routeCondit");
                    swithElement.addElement("workflow:case").addAttribute("to",toName).setText("${wf:actionData('"+fromName+"')"+routeCondit+"}");
                }
            }
        }
    }


    public static void addFork(Document document, String forkName,List<String> forkTos){
        //获取根元素
        Element rootElement = document.getRootElement();
        Element forkElement = rootElement.addElement("workflow:fork").addAttribute("name", forkName);
        if(CollectionUtil.isNotEmpty(forkTos)){
            for (String forkTo : forkTos) {
                forkElement.addElement("workflow:path").addAttribute("start",forkTo);
            }
        }
    }

    public static void addJoin(Document document, String joinName,String joinTo){
        document.getRootElement().addElement("workflow:join").addAttribute("name", joinName).addAttribute("to",joinTo);
    }

}
